package test;

import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

public class MathExerciseGenerator {
    private static final Random random = new Random();

    // 运算类型枚举
    public enum OpType {
        ADD, SUB, MUL, DIV, ADD_SUB, MUL_DIV, ALL_MIXED
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 输入题目数量
        System.out.print("请输入题目数量: ");
        int count = scanner.nextInt();

        // 输入数字个数
        System.out.print("请输入数字个数(2或3): ");
        int numCount = scanner.nextInt();
        while (numCount != 2 && numCount != 3) {
            System.out.print("请重新输入2或3: ");
            numCount = scanner.nextInt();
        }

        // 选择运算类型
        System.out.println("请选择运算类型:");
        System.out.println("1. 纯加法");
        System.out.println("2. 纯减法");
        System.out.println("3. 纯乘法");
        System.out.println("4. 纯除法");
        System.out.println("5. 加减法混合");
        System.out.println("6. 乘除法混合");
        System.out.println("7. 加减乘除混合");
        int opChoice = scanner.nextInt();
        OpType opType = getOpType(opChoice);

        // 输入行列格式
        System.out.print("请输入每行显示题目数量: ");
        int cols = scanner.nextInt();
        while (cols < 1) {
            System.out.print("请输入正整数: ");
            cols = scanner.nextInt();
        }

        // 生成题目
        List<String> exercises = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            exercises.add(generateExercise(numCount, opType));
        }

        // 打印题目
        printExercises(exercises, cols);

        // 保存到CSV
        System.out.print("请输入保存文件名(无需后缀): ");
        String filename = scanner.next() + ".csv";
        saveToCSV(exercises, filename);
        System.out.println("题目已保存至 " + filename);

        scanner.close();
    }

    // 转换选择为运算类型
    private static OpType getOpType(int choice) {
        return switch (choice) {
            case 1 -> OpType.ADD;
            case 2 -> OpType.SUB;
            case 3 -> OpType.MUL;
            case 4 -> OpType.DIV;
            case 5 -> OpType.ADD_SUB;
            case 6 -> OpType.MUL_DIV;
            case 7 -> OpType.ALL_MIXED;
            default -> throw new IllegalArgumentException("无效运算类型");
        };
    }

    // 生成单道题目
    public static String generateExercise(int numCount, OpType opType) {
        if (numCount == 2) {
            return generateTwoNumExercise(opType);
        } else {
            return generateThreeNumExercise(opType);
        }
    }

    // 生成2个数运算
    private static String generateTwoNumExercise(OpType opType) {
        while (true) {
            int a = random.nextInt(98) + 1; // 1-99
            int b = random.nextInt(98) + 1;
            char op = getOperator(opType);

            // 验证运算合法性
            if (op == '+') {
                int res = a + b;
                if (res < 100) return a + " + " + b + " = ";
            } else if (op == '-') {
                if (a > b) return a + " - " + b + " = ";
            } else if (op == '*') {
                int res = a * b;
                if (res < 100) return a + " × " + b + " = ";
            } else if (op == '/') {
                // 确保整除且结果为正整数
                if (a % b == 0 && a / b > 0) return a + " ÷ " + b + " = ";
            }
        }
    }

    // 生成3个数运算
    private static String generateThreeNumExercise(OpType opType) {
        while (true) {
            int a = random.nextInt(98) + 1;
            int b = random.nextInt(98) + 1;
            int c = random.nextInt(98) + 1;
            char op1 = getOperator(opType);
            char op2 = getOperator(opType);

            // 计算第一步结果
            Integer step1 = calculateStep(a, b, op1);
            if (step1 == null || step1 <= 0 || step1 >= 100) continue;

            // 计算最终结果
            Integer finalRes = calculateStep(step1, c, op2);
            if (finalRes != null && finalRes > 0 && finalRes < 100) {
                return a + " " + op1 + " " + b + " " + op2 + " " + c + " = ";
            }
        }
    }

    // 计算单步运算结果（不合法返回null）
    private static Integer calculateStep(int x, int y, char op) {
        switch (op) {
            case '+' -> {
                int res = x + y;
                return res < 100 ? res : null;
            }
            case '-' -> {
                return x > y ? x - y : null;
            }
            case '*' -> {
                int res = x * y;
                return res < 100 ? res : null;
            }
            case '/' -> {
                return (y != 0 && x % y == 0) ? x / y : null;
            }
            default -> {
                return null;
            }
        }
    }

    // 获取符合类型的运算符
    private static char getOperator(OpType opType) {
        List<Character> possibleOps = new ArrayList<>();
        switch (opType) {
            case ADD -> possibleOps.add('+');
            case SUB -> possibleOps.add('-');
            case MUL -> possibleOps.add('*');
            case DIV -> possibleOps.add('/');
            case ADD_SUB -> { possibleOps.add('+'); possibleOps.add('-'); }
            case MUL_DIV -> { possibleOps.add('*'); possibleOps.add('/'); }
            case ALL_MIXED -> { possibleOps.add('+'); possibleOps.add('-'); possibleOps.add('*'); possibleOps.add('/'); }
        }
        return possibleOps.get(random.nextInt(possibleOps.size()));
    }

    // 按格式打印题目
    private static void printExercises(List<String> exercises, int cols) {
        System.out.println("\n生成的题目:");
        for (int i = 0; i < exercises.size(); i++) {
            System.out.printf("%-20s", exercises.get(i));
            if ((i + 1) % cols == 0) System.out.println();
        }
        System.out.println();
    }

    // 保存到CSV文件
    public static void saveToCSV(List<String> exercises, String filename) {
        try (FileWriter writer = new FileWriter(filename)) {
            for (String ex : exercises) {
                writer.write(ex.replace("=", "") + ","); // 去掉等号便于后续处理
            }
        } catch (IOException e) {
            System.err.println("保存文件失败: " + e.getMessage());
        }
    }
}